/*
		串口数据发送模块使用说明：	
					数据的发送：
							1. 只有当	send_data_valid 信号高电平的时候模块才正常工作
							2. bit_select 比特率设计  1 ：9600		2 ：19200		3 ：38400		4 ：57200		5 ：115200
							3.	txd_done 完成信号，高电平有效
							4.	txd 传输串行数据
							5.	txd_normal	数据检测信号 -> 高电平 ：数据传输正常
							6. 当 send_data_start 开始信号为1的时候传输一次
							7.	send_data_valid 传输有效信号,当为高电平的时候为传输数据，低电平的时候为空闲状态
							8.数据写入后如果数据不改变将会一直保持
							9.数据的传输方式：先传输低位在到高位
					
*/


module uart_send(

	input		wire 				clk					,			//系统时钟信号
	input		wire 				ret_n		 			,			//复位信号
	input		wire 	[2:0]		bit_select			,			//比特率选择信号
	input		wire 	[7:0]		send_data			,			//传输的数据
	input		wire 				send_data_start	,			//数据传输，来一个高电平传输一次
	
	output	reg 				txd					,			//传输的数据串行信号
	output	reg				txd_done							//数据传输完成信号
	
);

	reg 	[12:0]	cnt_bit;	 					//比特计数器
	reg 	[2:0]		bit_judge; 					//判断信号，同时对 bit_select 信号进行寄存
	reg 	[12:0]	cnt_bit_max;				//比特计数器计算最大值
	reg 	[3:0]		cnt_send;					//数据传输计数器
	reg	[7:0]		send_data_keep;			//对传输的数据进行缓存
	reg				bit_clk;						//比特传输时钟信号
	reg				send_data_valid;			//传输有效信号,当为高电平的时候为传输数据
	
	parameter 	cnt_send_max = 4'd11;					//数据传输计数器计数最大值
	
	
	/*
		以下为比特传输时钟的编写，同时也是比特率的设计
	*/
	
	//对 bit_judge 比特率选择的判断信号进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			bit_judge <= 3'd0;
		else 
			bit_judge <= bit_select;
	
	//对 send_data_valid 传输开始有效信号进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			send_data_valid <= 1'b0;
		else if(send_data_start)
			send_data_valid <= 1'b1;
		else if(cnt_send == cnt_send_max)
			send_data_valid <= 1'b0;
		else 
			send_data_valid <= send_data_valid;
	
	
	//对比特计数器进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit <= 13'd0;
		else if(send_data_valid == 1'b1)
			begin 
				if(cnt_bit == cnt_bit_max - 1)
					cnt_bit <= 13'd0;
				else 
					cnt_bit <= cnt_bit + 1'b1;
			end 
		else 
			cnt_bit <= 13'd0;

	//对 cnt_bit_max 比特计数器计数最大值进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_max <= 13'd0;
		else 
			case(bit_judge)
					1 	:	cnt_bit_max <= 13'd5208;
					2	:	cnt_bit_max <= 13'd2604;
					3	:	cnt_bit_max <= 13'd1302;
					4	:	cnt_bit_max <= 13'd868;
					5	:	cnt_bit_max <= 13'd433;
				default	: cnt_bit_max <= 13'd0;
			endcase 
			
	//产生 bit_clk 比特传输时钟信号
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			bit_clk <= 1'b0;
		else if(cnt_bit == cnt_bit_max - 2)
			bit_clk <= 1'b1;
		else 
			bit_clk <= 1'b0;
			
			
			
	/*
		以下为数据传输的编写,数据传输计数器采用的时钟信号 ：bit_clk
	*/
	
	
	//对 send_data 传输数据进行缓存,并设计使能信号
	//reg	[7:0]		send_data_keep;	//对传输的数据进行缓存
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			send_data_keep <= 8'd0;
		else if(send_data_start)
			send_data_keep <= send_data;
		else 
			send_data_keep <= send_data_keep;
	
	//对 cnt_send 数据传输计数器进行编写
	//reg 	[3:0]		cnt_send;		//数据传输计数器
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_send <= 4'd0;
		else if(cnt_send == cnt_send_max)
			cnt_send <= 4'd0;
		else if(bit_clk)
			cnt_send <= cnt_send + 1'b1;
		else 
			cnt_send <= cnt_send;
			
	
	//对数据传输的线性序列机进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			txd <= 1'b1;
		else 
			case(cnt_send)
					 0		:	txd <= 1'b1;
					 1		:	txd <= 1'b0;
					 2		:	txd <= send_data_keep[0];
					 3		: 	txd <= send_data_keep[1];
					 4		: 	txd <= send_data_keep[2];
					 5		: 	txd <= send_data_keep[3];
					 6		: 	txd <= send_data_keep[4];
					 7		: 	txd <= send_data_keep[5];
					 8		: 	txd <= send_data_keep[6];
					 9		: 	txd <= send_data_keep[7];
					 10	: 	txd <= 1'b0;
				 default :	txd <= 1'b1;
			endcase 
		
			 
	//对 txd_done 数据传输一次完成信号进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			txd_done <= 1'b0;
		else if(cnt_send == 4'd11)
			txd_done <= 1'b1;
		else 
			txd_done <= 1'b0;
			




endmodule 
































